#include <algorithm>
#include <array>
#include <bits/types/clock_t.h>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

#include "YArray.h"

using namespace std;
long get_a_target_long() {
    cout << "target(0~" << RAND_MAX << ")";
    long target;
    cin >> target;
    return target;
}
std::string get_a_target_string() {
    char buf[10];
    long target = 0;
    cout << "target(0~" << RAND_MAX << ")";
    cin >> target;
    snprintf(buf, 10, "%ld", target);
    return string(buf);
}
int compare(const void* a, const void* b) { return (*(long*)a - *(long*)b); }
int compareString(const void* a, const void* b) {
    if (*(string*)a > *(string*)b)
        return 1;
    else if (*(string*)a < *(string*)b)
        return -1;
    else
        return 0;
}

//////////////////////////////////////////////////////
#include <array>
#include <cstdlib>
#include <ctime>
#define MAX_SIZE 500000
namespace jj01 {
void testArray(const std::string& pvar) {
    std::cout << "\t\ttest array:" << std::endl;
    Yt::array<long, MAX_SIZE> ta;
    clock_t time = clock();
    for (long i = 0; i != MAX_SIZE; ++i) {
        ta[i] = rand();
    }
    cout << pvar << " time:" << clock() - time << endl;
    cout << pvar << " size:" << ta.size() << endl;
    cout << pvar << " front:" << ta.front() << endl;
    cout << pvar << " back:" << ta.back() << endl;
    cout << pvar << " data:" << ta.data() << endl;

    long target = get_a_target_long();

    time = clock();
    qsort(ta.data(), MAX_SIZE, sizeof(long), compare);

    long* pItem =
        (long*)bsearch(&target, ta.data(), MAX_SIZE, sizeof(long), compare);
    if (pItem) {
        cout << pvar << "find target:" << *pItem << endl;
    } else {
        cout << pvar << "no find target" << endl;
    }
}
} // namespace jj01

////////////////////////////////////////////////////
#include "cstdio"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
#include <string.h>
#include <vector>

namespace jj02 {
void testVector(const std::string& pvar, const long& value) {
    cout << "\t\ttestvector:" << endl;
    std::vector<std::string> c;
    char buf[10];
    clock_t time = clock();
    for (long i = 0; i != value; ++i) {
        try {
            snprintf(buf, 10, "%d", rand());
            c.push_back(string(buf));
        } catch (exception& p) {
            cout << "i:" << i << "\t" << p.what() << endl;
            abort();
        }
    }
    cout << pvar << " time:" << clock() - time << endl;
    cout << pvar << " size:" << c.size() << endl;
    cout << pvar << " maxsize:" << c.max_size() << endl;
    cout << pvar << " capacity:" << c.capacity() << endl;
    cout << pvar << " front:" << c.front() << endl;
    cout << pvar << " back:" << c.back() << endl;
    cout << pvar << " data:" << c.data() << endl;

    //1
    string target = get_a_target_string();

    std::vector<string>::iterator it = std::find(c.begin(), c.end(), target);
    if (it != c.end()) {
        cout << pvar << " find target" << *it << endl;
    } else {
        cout << pvar << " no find target" << endl;
    }
    //2
    sort(c.begin(),c.end());

    auto pit = (string *)bsearch(&target, c.data(),c.size(),sizeof(string),compareString);
    if(pit)
    {
       cout << pvar << " find target1" << *pit << endl;
    } else {
        cout << pvar << " no find target1" << endl;
    }
}
} // namespace jj02
////////////////////////////////////////////////////
#include "cstdio"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
#include <string.h>
#include <list>

namespace jj03 {
void testList(const std::string& pvar, const long& value) {
    cout << "\t\ttestlist:" << endl;
    std::list<std::string> c;
    char buf[10];
    clock_t time = clock();
    for (long i = 0; i != value; ++i) {
        try {
            snprintf(buf, 10, "%d", rand());
            c.push_back(string(buf));
        } catch (exception& p) {
            cout << "i:" << i << "\t" << p.what() << endl;
            abort();
        }
    }
    cout << pvar << " time:" << clock() - time << endl;
    cout << pvar << " size:" << c.size() << endl;
    cout << pvar << " maxsize:" << c.max_size() << endl;
    // cout << pvar << " capacity:" << c.capacity() << endl;
    cout << pvar << " front:" << c.front() << endl;
    cout << pvar << " back:" << c.back() << endl;
    // cout << pvar << " data:" << c.data() << endl;

    //1
    string target = get_a_target_string();

    auto it = std::find(c.begin(), c.end(), target);
    if (it != c.end()) {
        cout << pvar << " find target" << *it << endl;
    } else {
        cout << pvar << " no find target" << endl;
    }
    //2
    c.sort();
}
} // namespace jj03
////////////////////////////////////////////////////
#include "cstdio"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
#include <string.h>
#include <forward_list>

namespace jj04 {
void testForwardList(const std::string& pvar, const long& value) {
    cout << "\t\ttestforwardlist:" << endl;
    std::forward_list<std::string> c;
    char buf[10];
    clock_t time = clock();
    for (long i = 0; i != value; ++i) {
        try {
            snprintf(buf, 10, "%d", rand());
            c.push_front(string(buf));
        } catch (exception& p) {
            cout << "i:" << i << "\t" << p.what() << endl;
            abort();
        }
    }
    cout << pvar << " time:" << clock() - time << endl;
    // cout << pvar << " size:" << c.size() << endl;
    cout << pvar << " maxsize:" << c.max_size() << endl;
    // cout << pvar << " capacity:" << c.capacity() << endl;
    cout << pvar << " front:" << c.front() << endl;
    // cout << pvar << " back:" << c.back() << endl;
    // cout << pvar << " data:" << c.data() << endl;

    //1
    string target = get_a_target_string();

    auto it = std::find(c.begin(), c.end(), target);
    if (it != c.end()) {
        cout << pvar << " find target" << *it << endl;
    } else {
        cout << pvar << " no find target" << endl;
    }
    //2
    c.sort();
}
}
////////////////////////////////////////////////////
#include "cstdio"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
#include <string.h>
#include <deque>

namespace jj05 {
void testDeque(const std::string& pvar, const long& value) {
    cout << "\t\ttest"<<pvar<<":"<< endl;
    std::deque<std::string> c;
    char buf[10];
    clock_t time = clock();
    for (long i = 0; i != value; ++i) {
        try {
            snprintf(buf, 10, "%d", rand());
            c.push_back(string(buf));
        } catch (exception& p) {
            cout << "i:" << i << "\t" << p.what() << endl;
            abort();
        }
    }
    cout << pvar << " time:" << clock() - time << endl;
    cout << pvar << " size:" << c.size() << endl;
    cout << pvar << " maxsize:" << c.max_size() << endl;
    // cout << pvar << " capacity:" << c.capacity() << endl;
    cout << pvar << " front:" << c.front() << endl;
    cout << pvar << " back:" << c.back() << endl;
    // cout << pvar << " data:" << c.data() << endl;

    //1
    string target = get_a_target_string();

    auto it = std::find(c.begin(), c.end(), target);
    if (it != c.end()) {
        cout << pvar << " find target" << *it << endl;
    } else {
        cout << pvar << " no find target" << endl;
    }
    //2
    sort(c.begin(),c.end());
}
}
#include "YInheritTest.h"
void  testContainerMain() {
    srand(time(NULL));
    // 1
    //jj01::testArray("array");
    //2
    // jj02::testVector("vector", MAX_SIZE);
    //3
    // jj03::testList("list", MAX_SIZE);
     //4
    // jj04::testForwardList("forwardlist",MAX_SIZE);
     //5
    // jj05::testDeque("deque",MAX_SIZE);
    //6
    Base *b  = new Base();
    b->printTest();
    
    cout<<"///////////////////////////////////"<<endl;

    Base *c = new Child();
    c->printTest();
}
